<template>
  <div class="performance-monitor">
    <div class="monitor-header">
      <h2>性能监控面板</h2>
      <div class="controls">
        <el-button @click="startMonitoring" :disabled="isMonitoring" type="primary">
          开始监控
        </el-button>
        <el-button @click="stopMonitoring" :disabled="!isMonitoring" type="danger">
          停止监控
        </el-button>
        <el-button @click="clearData" type="warning">
          清除数据
        </el-button>
      </div>
    </div>

    <div class="performance-stats">
      <div class="stat-card">
        <div class="stat-icon">⚡</div>
        <div class="stat-content">
          <div class="stat-value">{{ performanceMetrics.fps || 0 }}</div>
          <div class="stat-label">FPS</div>
        </div>
      </div>
      <div class="stat-card">
        <div class="stat-icon">🕐</div>
        <div class="stat-content">
          <div class="stat-value">{{ performanceMetrics.loadTime || 0 }}ms</div>
          <div class="stat-label">页面加载时间</div>
        </div>
      </div>
      <div class="stat-card">
        <div class="stat-icon">📊</div>
        <div class="stat-content">
          <div class="stat-value">{{ performanceMetrics.memory || 0 }}MB</div>
          <div class="stat-label">内存使用</div>
        </div>
      </div>
      <div class="stat-card">
        <div class="stat-icon">🔍</div>
        <div class="stat-content">
          <div class="stat-value">{{ slowFunctions.length }}</div>
          <div class="stat-label">慢函数</div>
        </div>
      </div>
    </div>

    <div class="monitoring-sections">
      <!-- 慢函数监控 -->
      <div class="monitor-section">
        <h3>慢函数监控</h3>
        <div class="function-list">
          <div v-for="func in slowFunctions" :key="func.name" class="function-item">
            <div class="function-name">{{ func.name }}</div>
            <div class="function-time" :class="getTimeClass(func.time)">
              {{ func.time }}ms
            </div>
            <div class="function-source">{{ func.source }}</div>
          </div>
        </div>
      </div>

      <!-- 资源加载监控 -->
      <div class="monitor-section">
        <h3>资源加载监控</h3>
        <div class="resource-list">
          <div v-for="resource in resourceMetrics" :key="resource.name" class="resource-item">
            <div class="resource-name">{{ resource.name }}</div>
            <div class="resource-size">{{ formatBytes(resource.size) }}</div>
            <div class="resource-time">{{ resource.loadTime }}ms</div>
            <div class="resource-status" :class="resource.status">{{ resource.status }}</div>
          </div>
        </div>
      </div>

      <!-- 性能建议 -->
      <div class="monitor-section">
        <h3>性能优化建议</h3>
        <div class="suggestions">
          <div v-for="suggestion in performanceSuggestions" :key="suggestion.id" class="suggestion-item">
            <div class="suggestion-icon">{{ suggestion.icon }}</div>
            <div class="suggestion-content">
              <div class="suggestion-title">{{ suggestion.title }}</div>
              <div class="suggestion-description">{{ suggestion.description }}</div>
            </div>
            <div class="suggestion-priority" :class="suggestion.priority">
              {{ suggestion.priority }}
            </div>
          </div>
        </div>
      </div>

      <!-- 实时日志 -->
      <div class="monitor-section">
        <h3>实时性能日志</h3>
        <div class="log-container">
          <div v-for="log in performanceLogs" :key="log.id" class="log-item" :class="log.level">
            <span class="log-time">{{ log.time }}</span>
            <span class="log-message">{{ log.message }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { ElButton } from 'element-plus'

// 响应式数据
const isMonitoring = ref(false)
const performanceMetrics = reactive({
  fps: 0,
  loadTime: 0,
  memory: 0
})

const slowFunctions = ref([])
const resourceMetrics = ref([])
const performanceLogs = ref([])
const performanceSuggestions = ref([])

// 监控相关变量
let monitoringInterval = null
let frameCount = 0
let lastTime = performance.now()

// 开始监控
const startMonitoring = () => {
  isMonitoring.value = true
  addLog('info', '开始性能监控')
  
  // 监控FPS
  monitoringInterval = setInterval(() => {
    updateFPS()
    updateMemoryUsage()
    checkSlowFunctions()
  }, 1000)
  
  // 监控资源加载
  monitorResourceLoading()
  
  // 监控页面性能
  monitorPagePerformance()
}

// 停止监控
const stopMonitoring = () => {
  isMonitoring.value = false
  if (monitoringInterval) {
    clearInterval(monitoringInterval)
    monitoringInterval = null
  }
  addLog('info', '停止性能监控')
}

// 清除数据
const clearData = () => {
  slowFunctions.value = []
  resourceMetrics.value = []
  performanceLogs.value = []
  performanceSuggestions.value = []
  addLog('info', '清除所有监控数据')
}

// 更新FPS
const updateFPS = () => {
  const now = performance.now()
  const delta = now - lastTime
  frameCount++
  
  if (delta >= 1000) {
    performanceMetrics.fps = Math.round((frameCount * 1000) / delta)
    frameCount = 0
    lastTime = now
  }
}

// 更新内存使用
const updateMemoryUsage = () => {
  if (performance.memory) {
    performanceMetrics.memory = Math.round(performance.memory.usedJSHeapSize / 1024 / 1024)
  }
}

// 检查慢函数
const checkSlowFunctions = () => {
  // 监控常见的性能问题
  const startTime = performance.now()
  
  // 检查DOM查询
  const elements = document.querySelectorAll('*')
  const queryTime = performance.now() - startTime
  
  if (queryTime > 10) {
    addSlowFunction('DOM查询', queryTime, 'document.querySelectorAll')
  }
  
  // 检查重排重绘
  const styleStart = performance.now()
  document.body.offsetHeight // 强制重排
  const styleTime = performance.now() - styleStart
  
  if (styleTime > 5) {
    addSlowFunction('样式计算', styleTime, 'offsetHeight')
  }
}

// 添加慢函数记录
const addSlowFunction = (name, time, source) => {
  const existing = slowFunctions.value.find(f => f.name === name)
  if (existing) {
    existing.time = time
    existing.count++
  } else {
    slowFunctions.value.push({
      name,
      time,
      source,
      count: 1,
      timestamp: Date.now()
    })
  }
  
  if (time > 100) {
    addLog('warning', `检测到慢函数: ${name} (${time}ms)`)
  }
}

// 监控资源加载
const monitorResourceLoading = () => {
  const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      if (entry.entryType === 'resource') {
        resourceMetrics.value.push({
          name: entry.name.split('/').pop(),
          size: entry.transferSize || 0,
          loadTime: Math.round(entry.duration),
          status: entry.transferSize > 0 ? 'success' : 'error'
        })
      }
    }
  })
  
  observer.observe({ entryTypes: ['resource'] })
}

// 监控页面性能
const monitorPagePerformance = () => {
  window.addEventListener('load', () => {
    const navigation = performance.getEntriesByType('navigation')[0]
    performanceMetrics.loadTime = Math.round(navigation.loadEventEnd - navigation.fetchStart)
    
    addLog('info', `页面加载完成: ${performanceMetrics.loadTime}ms`)
    
    // 生成性能建议
    generatePerformanceSuggestions()
  })
}

// 生成性能建议
const generatePerformanceSuggestions = () => {
  const suggestions = []
  
  // 检查图片优化
  const images = document.querySelectorAll('img')
  const largeImages = Array.from(images).filter(img => {
    return img.naturalWidth > 1920 || img.naturalHeight > 1080
  })
  
  if (largeImages.length > 0) {
    suggestions.push({
      id: 'image-optimization',
      icon: '🖼️',
      title: '图片优化',
      description: `发现 ${largeImages.length} 张大图片，建议压缩或使用WebP格式`,
      priority: 'high'
    })
  }
  
  // 检查CSS优化
  const stylesheets = document.querySelectorAll('link[rel="stylesheet"]')
  if (stylesheets.length > 5) {
    suggestions.push({
      id: 'css-optimization',
      icon: '🎨',
      title: 'CSS优化',
      description: `发现 ${stylesheets.length} 个CSS文件，建议合并减少HTTP请求`,
      priority: 'medium'
    })
  }
  
  // 检查JavaScript优化
  const scripts = document.querySelectorAll('script[src]')
  if (scripts.length > 10) {
    suggestions.push({
      id: 'js-optimization',
      icon: '📜',
      title: 'JavaScript优化',
      description: `发现 ${scripts.length} 个JS文件，建议合并或使用动态导入`,
      priority: 'medium'
    })
  }
  
  // 检查内存使用
  if (performanceMetrics.memory > 100) {
    suggestions.push({
      id: 'memory-optimization',
      icon: '💾',
      title: '内存优化',
      description: `内存使用 ${performanceMetrics.memory}MB，建议检查内存泄漏`,
      priority: 'high'
    })
  }
  
  // 检查慢函数
  if (slowFunctions.value.length > 0) {
    suggestions.push({
      id: 'function-optimization',
      icon: '⚡',
      title: '函数优化',
      description: `发现 ${slowFunctions.value.length} 个慢函数，建议优化算法`,
      priority: 'high'
    })
  }
  
  performanceSuggestions.value = suggestions
}

// 添加日志
const addLog = (level, message) => {
  performanceLogs.value.unshift({
    id: Date.now(),
    time: new Date().toLocaleTimeString(),
    level,
    message
  })
  
  // 限制日志数量
  if (performanceLogs.value.length > 100) {
    performanceLogs.value = performanceLogs.value.slice(0, 100)
  }
}

// 工具函数
const getTimeClass = (time) => {
  if (time > 100) return 'critical'
  if (time > 50) return 'warning'
  return 'normal'
}

const formatBytes = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 页面卸载时清理
onUnmounted(() => {
  stopMonitoring()
})

// 初始化
onMounted(() => {
  addLog('info', '性能监控面板已加载')
  
  // 检测外部脚本性能问题
  const detectExternalScripts = () => {
    const scripts = Array.from(document.scripts)
    const externalScripts = scripts.filter(script => {
      return script.src && !script.src.includes(window.location.origin)
    })
    
    if (externalScripts.length > 0) {
      addLog('warning', `检测到 ${externalScripts.length} 个外部脚本，可能影响性能`)
      
      externalScripts.forEach(script => {
        addLog('info', `外部脚本: ${script.src}`)
      })
    }
  }
  
  setTimeout(detectExternalScripts, 2000)
})
</script>

<style scoped>
.performance-monitor {
  padding: 20px;
  background: #f8fafc;
  min-height: 100vh;
}

.monitor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
  padding: 20px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.monitor-header h2 {
  color: #1f2937;
  font-size: 24px;
  font-weight: 700;
}

.controls {
  display: flex;
  gap: 10px;
}

.performance-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background: white;
  padding: 20px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  gap: 15px;
}

.stat-icon {
  font-size: 32px;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #e0e7ff;
  border-radius: 50%;
}

.stat-content {
  flex: 1;
}

.stat-value {
  font-size: 24px;
  font-weight: 700;
  color: #1f2937;
}

.stat-label {
  font-size: 14px;
  color: #6b7280;
}

.monitoring-sections {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
}

.monitor-section {
  background: white;
  padding: 20px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.monitor-section h3 {
  color: #1f2937;
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 2px solid #e5e7eb;
}

.function-list, .resource-list, .suggestions, .log-container {
  max-height: 300px;
  overflow-y: auto;
}

.function-item, .resource-item, .suggestion-item, .log-item {
  display: flex;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #f3f4f6;
  gap: 10px;
}

.function-item:last-child, .resource-item:last-child, .suggestion-item:last-child, .log-item:last-child {
  border-bottom: none;
}

.function-name, .resource-name {
  flex: 1;
  font-weight: 500;
  color: #374151;
}

.function-time, .resource-time {
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
}

.function-time.normal {
  background: #d1fae5;
  color: #065f46;
}

.function-time.warning {
  background: #fef3c7;
  color: #92400e;
}

.function-time.critical {
  background: #fee2e2;
  color: #991b1b;
}

.function-source, .resource-size, .resource-status {
  font-size: 12px;
  color: #6b7280;
}

.resource-status.success {
  color: #16a34a;
}

.resource-status.error {
  color: #dc2626;
}

.suggestion-icon {
  font-size: 20px;
  width: 30px;
  text-align: center;
}

.suggestion-content {
  flex: 1;
}

.suggestion-title {
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 4px;
}

.suggestion-description {
  font-size: 14px;
  color: #6b7280;
}

.suggestion-priority {
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
}

.suggestion-priority.high {
  background: #fee2e2;
  color: #991b1b;
}

.suggestion-priority.medium {
  background: #fef3c7;
  color: #92400e;
}

.suggestion-priority.low {
  background: #d1fae5;
  color: #065f46;
}

.log-time {
  font-size: 12px;
  color: #9ca3af;
  min-width: 80px;
}

.log-message {
  flex: 1;
  font-size: 14px;
}

.log-item.info .log-message {
  color: #374151;
}

.log-item.warning .log-message {
  color: #92400e;
}

.log-item.error .log-message {
  color: #991b1b;
}

@media (max-width: 768px) {
  .monitor-header {
    flex-direction: column;
    gap: 15px;
  }
  
  .controls {
    flex-wrap: wrap;
  }
  
  .monitoring-sections {
    grid-template-columns: 1fr;
  }
}
</style>
